﻿using System;
using System.Linq.Expressions;
using System.Reflection;
using CrmClient.QueryConvert;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;

namespace CrmClient.Mapping
{
    internal class MappingUtils
    {
        public static CrmAttrName GetCrmAttributeName(MemberInfo member)
        {
            return GetCrmAttributeName(member, null);
        }

        public static CrmAttrName GetCrmAttributeName(MemberInfo member, string alias)
        {
            string logicalName;
            var attributes = member.GetCustomAttributes(typeof(AttributeLogicalNameAttribute), true);
            if (attributes.Length == 0)
                logicalName = member.Name;
            else
                logicalName = ((AttributeLogicalNameAttribute)attributes[0]).LogicalName;
            var isId = member.Name == "Id";
            return alias == null ? new CrmAttrName(logicalName, isId) : new CrmAttrName(alias, logicalName, isId);
        }

        public static CrmAttrName GetCrmAttributeName(MemberExpression expression, PropertiesMap propertiesMap)
        {
            return GetCrmAttributeName(expression, propertiesMap, null);
        }

        public static CrmAttrName GetCrmAttributeName(MemberExpression expression, PropertiesMap propertiesMap, string alias)
        {
            if (expression.Expression is MemberExpression) //Если пришло выражение вида s.Director.Id, а нужный CrmEntityField на s.Director, то нужно до него добраться... (Пока я не могу представить ситуации, когда нужно брать имя атрибута со свойства Id)
                return GetCrmAttributeName((MemberExpression)expression.Expression, propertiesMap, alias);      
      
            if (propertiesMap == null)
                return GetCrmAttributeName(expression.Member, alias);
            else if (alias == null)
                return propertiesMap[expression.Member.Name].CrmAttr;
            else
            {
                var crmAttr = propertiesMap[expression.Member.Name].CrmAttr;
                return new CrmAttrName(alias, crmAttr.Name, crmAttr.IsId);
            }
        }

        public static string GetCrmEntityName(Type type)
        {
            var entityAttr = type.GetCustomAttributes(typeof(EntityLogicalNameAttribute), true);
            if (entityAttr.Length == 0)
                return type.Name;
            return ((EntityLogicalNameAttribute)entityAttr[0]).LogicalName;
        }
    }
}
